"""
认证相关API端点
===============

处理用户登录、注册、令牌刷新等认证功能
"""

from typing import Dict, Any

from fastapi import APIRouter, Depends, HTTPException, status
from dependency_injector.wiring import inject, Provide

from redfire_framework.core.exceptions import (
    UserNotFoundException,
    InvalidCredentialsError,
    UserAlreadyExistsException,
    ValidationException
)
from ...schemas.auth import (
    LoginRequest,
    RegisterRequest,
    TokenResponse,
    LoginResponse,
    RefreshTokenRequest,
    PasswordResetRequest,
    PasswordResetConfirmRequest
)
from ...schemas.user import UserResponse
from ...services.user_service import UserService
from ...containers import UserServiceContainer

Container = UserServiceContainer

router = APIRouter()


@router.post("/login", response_model=LoginResponse)
@inject
async def login(
    request: LoginRequest,
    user_service: UserService = Depends(Provide[UserServiceContainer.user_service]),
    jwt_manager = Depends(Provide[UserServiceContainer.jwt_manager])
):
    """用户登录"""
    try:
        # 验证用户凭证
        user = await user_service.authenticate_user(
            request.username, request.password
        )
        
        if not user:
            raise InvalidCredentialsError("Invalid username or password")
        
        # 创建令牌
        token_data = {
            "sub": str(user.id),
            "username": user.username,
            "email": user.email,
            "role": getattr(user, 'role', 'user')
        }
        
        access_token = jwt_manager.create_access_token(token_data)
        refresh_token = jwt_manager.create_refresh_token(token_data)
        
        # 转换用户对象为响应模型
        user_response = UserResponse(
            id=str(user.id),
            username=user.username,
            email=user.email,
            is_active=user.is_active,
            created_at=user.created_at
        )
        
        return LoginResponse(
            access_token=access_token,
            refresh_token=refresh_token,
            token_type="bearer",
            user=user_response
        )
        
    except (UserNotFoundException, InvalidCredentialsError):
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail="用户名或密码错误"
        )
    except Exception as e:
        import traceback
        error_detail = f"登录失败: {str(e)}"
        print(f"❌ 登录异常: {error_detail}")
        print(traceback.format_exc())
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail=error_detail
        )


@router.post("/register", response_model=UserResponse)
@inject
async def register(
    request: RegisterRequest,
    user_service: UserService = Depends(Provide[UserServiceContainer.user_service])
):
    """用户注册"""
    try:
        # 调试：打印接收到的密码信息
        print(f"🔍 register endpoint: password type={type(request.password)}, len={len(request.password)}, bytes_len={len(request.password.encode('utf-8'))}")
        print(f"🔍 register endpoint: password value={request.password[:50]}")
        
        # 创建用户（密码验证在服务层进行）
        user = await user_service.create_user(
            username=request.username,
            email=request.email,
            password=request.password,
            full_name=getattr(request, 'full_name', None),
            phone=getattr(request, 'phone', None)
        )
        
        return UserResponse(
            id=user.id,
            username=user.username,
            email=user.email,
            is_active=user.is_active,
            created_at=user.created_at
        )
        
    except UserAlreadyExistsException as e:
        raise HTTPException(
            status_code=status.HTTP_409_CONFLICT,
            detail=str(e)
        )
    except ValidationException as e:
        raise HTTPException(
            status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,
            detail=e.to_dict()
        )
    except Exception as e:
        import traceback
        error_detail = f"注册失败: {str(e)}"
        print(f"❌ 注册异常: {error_detail}")
        print(traceback.format_exc())
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail=error_detail
        )


@router.post("/refresh", response_model=TokenResponse)
@inject
async def refresh_token(
    request: RefreshTokenRequest,
    jwt_manager = Depends(Provide[UserServiceContainer.jwt_manager])
):
    """刷新访问令牌"""
    try:
        # 验证刷新令牌
        payload = jwt_manager.verify_token(request.refresh_token)
        if not payload or payload.get("type") != "refresh":
            raise HTTPException(
                status_code=status.HTTP_401_UNAUTHORIZED,
                detail="无效的刷新令牌"
            )
        
        # 创建新的访问令牌
        token_data = {
            "sub": payload.get("sub"),
            "username": payload.get("username"),
            "email": payload.get("email"),
            "role": payload.get("role", "user")
        }
        
        access_token = jwt_manager.create_access_token(token_data)
        
        return TokenResponse(
            access_token=access_token,
            refresh_token=request.refresh_token,  # 保持原刷新令牌
            token_type="bearer"
        )
        
    except Exception as e:
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail="令牌刷新失败"
        )


@router.post("/logout")
async def logout():
    """用户登出"""
    # 在实际实现中，这里应该将令牌加入黑名单
    # 或者删除相关的会话信息
    return {"message": "登出成功"}


@router.post("/password-reset")
@inject
async def request_password_reset(
    request: PasswordResetRequest,
    user_service: UserService = Depends(Provide[UserServiceContainer.user_service])
):
    """请求密码重置"""
    try:
        # 检查用户是否存在
        user = await user_service.get_user_by_email(request.email)
        if not user:
            # 为了安全，不透露用户是否存在
            return {"message": "如果邮箱存在，重置链接已发送"}
        
        # 在实际实现中，这里应该生成密码重置令牌并发送邮件
        # reset_token = jwt_manager.create_access_token({"email": request.email, "type": "password_reset"})
        # await email_service.send_password_reset_email(user.email, reset_token)
        
        return {"message": "密码重置链接已发送到您的邮箱"}
        
    except Exception as e:
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail="密码重置请求失败"
        )


@router.post("/password-reset/confirm")
@inject
async def confirm_password_reset(
    request: PasswordResetConfirmRequest,
    user_service: UserService = Depends(Provide[UserServiceContainer.user_service])
):
    """确认密码重置"""
    try:
        # 在实际实现中，这里应该验证重置令牌
        # 验证新密码强度
        if len(request.new_password) < 8:
            raise ValidationException("密码长度至少8位")
        
        # 更新密码（简化实现，实际应该通过令牌获取用户）
        # await user_service.update_password_by_token(request.token, request.new_password)
        
        return {"message": "密码重置成功"}
        
    except ValidationException as e:
        raise HTTPException(
            status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,
            detail=str(e)
        )
    except Exception as e:
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail="密码重置失败"
        )


@router.get("/me", response_model=UserResponse)
@inject
async def get_current_user_info(
    user_service: UserService = Depends(Provide[UserServiceContainer.user_service])
):
    """获取当前用户信息"""
    try:
        # 在实际实现中，这里应该从JWT令牌中获取用户ID
        # current_user_id = get_current_user_id_from_token()
        # user = await user_service.get_user_by_id(current_user_id)
        
        # 简化实现，返回示例用户信息
        return UserResponse(
            id=1,
            username="demo_user",
            email="demo@example.com",
            is_active=True,
            created_at="2024-01-01T00:00:00"
        )
        
    except Exception as e:
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail="获取用户信息失败"
        )
